package com.fanxj.service.impl;

import com.fanxj.Utils.CharsetDetectorUtils;
import com.fanxj.Utils.DynastyConverter;
import com.fanxj.Utils.ImportError;
import com.fanxj.Utils.ImportResult;
import com.fanxj.domain.DecadeType;
import com.fanxj.domain.GroupType;
import com.fanxj.domain.LocalType;
import com.fanxj.domain.Relic;
import com.fanxj.mapper.RelicMapper;
import com.fanxj.mapper.UserMapper;
import com.fanxj.service.RelicImportService;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.ValidationException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

import static com.fanxj.Utils.CharsetDetectorUtils.isLikelyUTF8;

@Service("RelicImportService")
public class RelicImportServiceImpl implements RelicImportService {

    @Autowired
    private RelicMapper relicMapper;
    @Autowired
    private UserMapper userMapper;

    public ImportResult processCSV(InputStream inputStream) {
        List<Relic> relics = new ArrayList<>();
        List<ImportError> errors = new ArrayList<>();

        try {
            // 将流缓存到字节数组
            byte[] bytes = IOUtils.toByteArray(inputStream); // 使用 Apache Commons IO
            ByteArrayInputStream bufferedStream = new ByteArrayInputStream(bytes);

//            // 1.动态检测编码
//            String encoding = CharsetDetectorUtils.detectEncoding(bufferedStream);
//            if (encoding == null) {
//                // 尝试强制按 UTF-8 解析
//                if (isLikelyUTF8(bufferedStream)) {
//                    encoding = "UTF-8";
//                } else {
//                    encoding = "GBK"; // 回退到 GBK
//                }
//            }
//            Charset charset = Charset.forName(encoding);
//            bufferedStream.reset(); // 重置流指针


            // 1. 检测编码并强制要求UTF-8
            String encoding = CharsetDetectorUtils.detectEncoding(bufferedStream);
            bufferedStream.reset();

            // 2. 严格校验编码是否为UTF-8
            if (encoding == null || !encoding.equalsIgnoreCase("UTF-8")) {
                System.out.println("文件编码格式为："+encoding);
                    throw new ValidationException("文件编码必须是UTF-8");
            }

            // 3. 设置字符集并解析
            Charset charset = StandardCharsets.UTF_8; // 强制使用UTF-8
            bufferedStream.reset();

            // 2. 根据编码创建 CSV 解析器
            CSVParser parser = new CSVParser(
                    new InputStreamReader(bufferedStream, charset),
                    CSVFormat.DEFAULT
                            .withFirstRecordAsHeader()
                            .withIgnoreEmptyLines(true)
                            .withTrim()
            );

            // 3. 校验表头
            List<String> headers = parser.getHeaderNames().stream()
                    .map(header -> header.replaceAll("[\\s\\p{C}]", "")) // 移除所有空白和不可见字符
                    .collect(Collectors.toList());

            List<String> requiredFields = Arrays.asList(
                     "name", "groupType", "localType",
                    "decadeType", "image", "types", "pattern","technology"
            );
            if (!new HashSet<>(headers).containsAll(requiredFields)) {
                List<String> missingFields = requiredFields.stream()
                        .filter(f -> !headers.contains(f))
                        .collect(Collectors.toList());
                throw new ValidationException("CSV 表头缺失关键字段"+missingFields+headers);
            }
            for (CSVRecord record : parser) {
                try {
                    Relic relic = parseRelicFromRecord(record);
                    String decadeType = relic.getDecadeType();
                    String groupType = relic.getGroupType();
                    String localType = relic.getLocalType();
                    String image = relic.getImage();
                    String decadeTypeNew = DynastyConverter.convert(decadeType);
                    DecadeType decadeTypeVerify=userMapper.findDecadeTypeByLabel(decadeTypeNew);
                    GroupType groupTypeVerify=userMapper.findGroupTypeByLabel("%"+groupType+"%");
                    LocalType localTypeVerify=userMapper.findLocalTypeByLabel("%"+localType+"%");
//                       自定义校验逻辑
//                       校验必填字段
                        if (decadeTypeVerify==null) {
                            throw new ValidationException("年代关键词不正确");
                        }
                        if (groupTypeVerify==null) {
                            throw new ValidationException("分类关键词不正确");
                        }
                        if (localTypeVerify==null) {
                        throw new ValidationException("地区关键词不正确");
                        }
                        // 校验图片路径格式
                        if (!image.startsWith("/images/images/")) {
                            throw new ValidationException("图片路径格式错误");
                        }
                   System.out.println(decadeType);
                   System.out.println(groupType);
                   System.out.println(localType);
                    relics.add(relic);
                } catch (Exception e) {
                    errors.add(new ImportError(
                            record.getRecordNumber(),
                            e.getMessage()
                    ));
                }
            }
            // 5. 批量插入数据库
            if (!relics.isEmpty()) {
                batchInsert(relics); // 批量插入
            }

            return new ImportResult(
                    true,
                    "成功导入 " + relics.size() + " 条，失败 " + errors.size() + " 条",
                    errors
            );

        } catch (Exception e) {
            return new ImportResult(false, "CSV 解析失败: " + e.getMessage());
        }
    }

    public String validateField(CSVRecord record, String field) throws ValidationException {
        String value = record.get(field);
        if (value == null || value.trim().isEmpty()) {
            throw new ValidationException(field + " 不能为空");
        }
        return value.trim();
    }
    private Relic parseRelicFromRecord(CSVRecord record) throws ValidationException {
        Relic relic = new Relic();
        relic.setName(validateField(record, "name"));
        relic.setGroupType(validateField(record, "groupType"));
        relic.setLocalType(validateField(record, "localType"));
        relic.setDecadeType(validateField(record, "decadeType"));
        relic.setImage(validateField(record,"image"));
        relic.setTypes(record.get("types"));
        relic.setPattern(record.get("pattern"));
        relic.setTechnology(record.get("technology"));
        return relic;
    }
    public void batchInsert(List<Relic> relics) {
        // MyBatis 批量插入
        relicMapper.batchInsert(relics);
    }
}
